
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author dtuanh
 */
public class DictionnaryImpl implements Dictionnary {
    //le fichier de entry
    public static final String FILE_ENTRY="./entries.dat";
    //le fichier de definition
    public static final String FILE_DEF="./defs.dat";
    //liste de entity
    private static List <EntityImpl> ls_entity=new ArrayList();
    private Entity current=null;
    //ajouter une entity
    public void addEntity(String term, CategoryType cate, Property[] props, String def) throws TermExisted, RemoteException {
           EntityImpl entity=new EntityImpl();
           WordImpl word=new WordImpl();
           word.setTerm(term);
           CategoryImpl cat=new CategoryImpl();
           cat.setCategory(cate);
           word.setCategory(cat);
           word.addProperty(props);
           entity.setDefinition(def);
           entity.setEntry(word);
           ls_entity.add(entity);
    }
//chercher un entity
    private EntityImpl search(String term)
    {
        for(int i=0;i<ls_entity.size();i++)
        {
            EntityImpl entity= (EntityImpl)ls_entity.get(i);
            if(entity.word.term.equalsIgnoreCase(term))
            {

                return entity;
            }
        }
        return null;
    }
    //supprimer une entity
    public void delEntity(String term) throws TermNotFound, RemoteException {
         EntityImpl entity=search(term);
         if(entity==null) throw new TermNotFound();
         else
             this.ls_entity.remove(entity);
    }

    //modifier la definition d'un mot
    public void modifDefinition(String term, String newdef) throws TermNotFound, RemoteException {
        EntityImpl entity=search(term);
         if(entity==null) throw new TermNotFound();
         else
         {
             entity.setDefinition(newdef);
         }
    }

    //comparer entre deux mots
    int compare (EntityImpl e1, EntityImpl e2){
        return e1.word.term.compareToIgnoreCase(e2.word.term);
    }

    //trirer la dictionnaire
    public void sortDict(boolean direct) throws RemoteException {
        for(int i=0;i<ls_entity.size();i++)
        {
            EntityImpl e_i=ls_entity.get(i);
            for(int j=i+1;j<ls_entity.size();j++)
            {
                EntityImpl e_j=ls_entity.get(j);
                // ascendant (terme) si direct = TRUE
                if(compare(e_i,e_j)>0&&direct)
                {
                    ls_entity.set(j, e_i);
                    ls_entity.set(i, e_j);
                    e_i=ls_entity.get(i);
                }
                //  descendant, DIRECT=FALSE
                if(compare(e_i,e_j)<0&&!direct)
                {
                    ls_entity.set(j, e_i);
                    ls_entity.set(i, e_j);
                    e_i=ls_entity.get(i);
                }
            }
        }

    }

   //charger la dictionnaire
    public long loadDict() throws DictFilesNotFound, RemoteException {
    try{
        //lire les fichier de entry et de definition
        DataInputStream in_entry=new DataInputStream(new FileInputStream(FILE_ENTRY));
        DataInputStream in_def=new DataInputStream(new FileInputStream(FILE_DEF));
        String entry=null;
        String def=null;
        //supprimer le memoire
        ls_entity.clear();
        while(true)
        {
            entry=in_entry.readLine();
            def=in_def.readLine();
            if(entry==null||def==null)  return (long)ls_entity.size();
            EntityImpl entity=new EntityImpl();
            Word word=DictionnaryHelper.readWord(entry);
            entity.setDefinition(DictionnaryHelper.readDefinition(def));
            entity.setEntry(word);
            this.ls_entity.add(entity);
        }


    }   catch (IOException ex) {
            Logger.getLogger(DictionnaryImpl.class.getName()).log(Level.SEVERE, null, ex);
            throw new DictFilesNotFound();
        }

        
    }

    //sauvegarder la dictionnaire sur le disk
    public void saveDict() throws RemoteException {
        if(ls_entity.size()==0)return;
        PrintWriter out_entry = null;
        PrintWriter out_def = null;
        try {
            out_entry = new PrintWriter(FILE_ENTRY);
            out_def = new PrintWriter(FILE_DEF);
            for(int i=0;i<ls_entity.size();i++)
            {
                 EntityImpl entity=(EntityImpl)ls_entity.get(i);
                 String txt_entity="["+i+","+entity.getEntry().myCategory().toFile()+","+entity.getEntry().toFile()+"]";
                 String txt_def=i+ ",«" + entity.getDefinition()+ "»";
                 out_entry.println(txt_entity);
                 out_def.println(txt_def);
            }
            out_entry.flush();
            out_def.flush();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(DictionnaryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            out_entry.close();
        }
    }

    //conseiller un mot
    public Entity findEntity(String term) throws TermNotFound, RemoteException {
      EntityImpl entity=search(term);
         if(entity==null) throw new TermNotFound();
      this.current=entity;
      return entity;
    }

    //premier mot
    public Entity fistEntity() throws DictEmpty, RemoteException {
      if(ls_entity.size()==0) throw new DictEmpty();
      this.current=ls_entity.get(0);
      return ls_entity.get(0);
    }

    //dernier mot
    public Entity lastEntity() throws DictEmpty, RemoteException {
          if(ls_entity.size()==0) throw new DictEmpty();
          this.current=ls_entity.get(ls_entity.size()-1);
        return ls_entity.get(ls_entity.size()-1);
    }

    //mot suivant
    public Entity nextEntity() throws DictEmpty, RemoteException {
        if(ls_entity.size()==0) throw new DictEmpty();

        int index= currentIndex();
        if(index>=0&&index<(ls_entity.size()-1))
        {
             current=ls_entity.get(index+1);
            return current;
        }

     return fistEntity();

    }
    //gerer l'entity actuel
    public int currentIndex()
    {
        for(int i=0;i<ls_entity.size();i++)
        {
            Entity tmp=(Entity)ls_entity.get(i);
            if(tmp==current)return i;
        }
        return -1;
    }

    //precedent entity
    public Entity prevEntity() throws DictEmpty, RemoteException {
        if(ls_entity.size()==0) throw new DictEmpty();
        int index= currentIndex();
        if(index>=1)
        {
            current=ls_entity.get(index-1);
            return (current);
        }

     return fistEntity();
    }

    //mombre de mots
    public long numEntities() throws RemoteException {
       return ls_entity.size();
    }

}
